const ncname = `[a-zA-Z_][\\-\\.0-9_a-zA-Z]*` //标签名称
const qnameCapture = `((?:${ncname}\\:)?${ncname})` //匹配标签名
const startTagOpen = new RegExp(`^<${qnameCapture}`) //标签开头的正则,捕获的内容是标签名
const endTag = new RegExp(`^<\\/${qnameCapture}[^>]*>`) //匹配标签结尾的</div>
const attribute =
  /^\s*([^\s"'<>\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/ //配置属性
const startTagClose = /^\s*(\/?)>/ //匹配标签结束的
const defaultTagRE = /\{\{((?:.|\r?\n)+?)\}\}/g //匹配{{}}

function createASTElement(tag, attrs) {
  return {
    tag, //标签
    attrs, //属性
    type: 1, //类型,元素类型1 ,
    children: [], //子节点
    parent: null, //父节点
  }
}
let root //根元素
let createParent //当前元素的父节点
// 数据结构,栈
let stack = []
// 开始标签
function start(tag, attrs) {
  let element = createASTElement(tag, attrs)
  if (!root) {
    root = element
  }
  createParent = element
  stack.push(element)
}
//文本标签
function charts(text) {
  text = text.replace("/s/g", "")
  if (text) {
    createParent.children.push({
      type: 3,
      text,
    })
  }
}

// 结束标签
function end(tag) {
  let element = stack.pop()
  createParent = stack[stack.length - 1]
  if (createParent) {
    //当前标签有父标签
    element.parent = createParent.tag
    createParent.children.push(element) //子集
  }
}
// 解析html
function parseHTML(html) {
  // 分类:无论什么结构无非是: 开始标签, 文本,结束标签
  //循环判断,为空结束
  while (html) {
    //为空时停止循环
    // 判断标签
    let textEnd = html.indexOf("<") //标签开始位置
    if (textEnd === 0) {
      //开始标签和结束标签都带<
      const startTagMatch = parseStartTag() //匹配开始标签内容
      if (startTagMatch) {
        start(startTagMatch.tagName, startTagMatch.attrs)
        // continue
      }
      //   结束标签
      let endTagMatch = html.match(endTag)
      if (endTagMatch) {
        advance(endTagMatch[0].length)
        end(endTagMatch[1])
      }
    }
    // 文本
    let text
    if (textEnd > 0) {
      // 获取文本内容,
      text = html.substring(0, textEnd)
    }
    // 删除已经处理的文本
    if (text) {
      advance(text.length)
      charts(text)
    }
    // break;
  }
  function parseStartTag() {
    // 解析开始标签
    const start = html.match(startTagOpen) //1.结果  2.false
    if (!start) return
    // 组装对象,创建ast语法树
    let match = {
      tagName: start[1],
      attrs: [],
    }
    // 删除开始标签
    advance(start[0].length)
    // 匹配属性,注意多个属性,需要遍历
    // 注意结束标签>
    let end, attr
    while (
      !(end = html.match(startTagClose)) &&
      (attr = html.match(attribute))
    ) {
      match.attrs.push({
        name: attr[1],
        value: attr[3],
      })
      // 删除属性
      advance(attr[0].length)
    }
    if (end) {
      //删除结束标签
      advance(end[0].length)
      return match
    }
  }
  function advance(n) {
    html = html.substring(n)
  }
  console.log(root)
  return root
}
/**
 * 编译方法
 * @param {*} el 元素
 */
export function compileToFunction(el) {
  let ast = parseHTML(el)
}
